<?php
/**
* DIXon Generation 1 - JavaScript Client Pages
* 
* PHP Bindings for PHP 5.2.x and above
* 
* Copyright (c) 2008, Artem Ploujnikov
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided  that the following conditions are met:
* 
*  * Redistributions of source code must retain the above copyright notice, this 
*    list of conditions and the following disclaimer.
*  * Redistributions in binary form must reproduce the above copyright notice, this 
* 	 list of conditions and the following disclaimer in the documentation and/or 
*    other materials provided with the distribution.
* *  Neither the name of Artem Ploujnikov nor the names of the project's contributors 
* 	 may be used to endorse or promote products derived from this software without 
*    specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
* POSSIBILITY OF SUCH DAMAGE. 
*/

/**
* Represents a single frame within a PHP of JavaScript
* stack trace. Usually, each frame corresponds to a function/method
* call.
* 
* @author Artem Ploujnikov 
*/
class DiXon_StackFrame implements IScriptable {
	/**
	* The name of the file where the error occurred
	* 
	* @var string 
	*/
	private $file;
	
	/**
	* The line where the error occurred
	* 
	* @var int
	*/
	private $line;
	
	/**
	* The name of the method from which the error
	* was thrown or triggered
	* 
	* @var string
	*/
	private $method;
	
	/**
	* Creates a new stack frame
	* 
	* @param string $method the name of the method where the error
	* 	occurred
	* 
	* @param string $file the name of the file where the error
	* occurred, if available
	* 
	* @param string $line the line number, if available
	*/
	public function __construct($method = null, $file = null, $line = null) {
		$this->method = $method;
		$this->file = $file;
		$this->line = $line;
	}
	
	
	
	/**
	* Returns the name of the method where the error
	* occurred
	* 
	* @return string
	*/
	public function getMethod() {
		return $this->method;
	}
	
	/**
	* Returns the name of the file responsible for the
	* error
	* 
	* @return string
	*/
	public function getFile() {
		return $this->file;
	}
	
	/**
	* Returns the number of the line, within the file returned by
	* getFile(), in which the error was triggered.
	* 
	* @return integer
	*/
	public function getLine() {
		return $this->line;
	}
	
	
	/**
	* Outputs a JavaScript representation of this error using
	* a DiXon script writer instance
	* 
	* @param DiXon_ScriptWriter $writer a script writer
	*/
	public function writeScript(DiXon_ScriptWriter $writer) {
		$writer
			->startObject()
			->writeKeyValuePair('method', $this->method)
			->endItem()
			->writeKeyValuePair('file', $this->file)
			->endItem()
			->writeKeyValuePair('line', $this->line)
			->endObject();
	}
	
	/**
	* Converts a PHP stack frame to a DiXon one
	* 
	* @param array $phpFrame a stack frame in the same format as the one returned
	* 	by debug_backtrace() or Exception::getTrace()
	* 
	* @return DiXon_StackFrame
	*/
	public static function toFrame($phpFrame) {
		return new DiXon_StackFrame(
			self::extractMethodName($phpFrame),
			isset($phpFrame['file']) ? $phpFrame['file'] : null,
			isset($phpFrame['line']) ? $phpFrame['line'] : null
		);
	}
	
	/**
	* Extracts the method name from a PHP stack trace
	* 
	* @param array $phpFrame a stack frame in the same format as the one returned
	* 	by debug_backtrace() or Exception::getTrace()
	*/
	private function extractMethodName($phpFrame) {		
		if (!empty($phpFrame['class'])) {
			$methodName = $phpFrame['class'] 
				. $phpFrame['type'] 
				. $phpFrame['function'];
		} else {
			$methodName = $phpFrame['function'];
		}
		return $methodName;		
	}

}

?>